//
//  BCResourceItem.m
//  断点上传和下载
//
//  Created by aaaa on 2020/5/8.
//  Copyright © 2020 aaaa. All rights reserved.

#import "BCResourceItem.h"
#import "BCResourceDownloadHelper.h"
#define ASYNC(...) dispatch_async(dispatch_get_global_queue(0,0), ^{ \
    __VA_ARGS__; \
});
@implementation BCResourceItem

- (instancetype)initWithUrl:(NSString *)url
{
    self = [super init];
    if (self) {
        _url = url;
        _downloadState = BCDownloadState_unDownload;
        _uploadState   = BCUploadState_unUpload;
        _recieveLength = [[[NSFileManager defaultManager] attributesOfItemAtPath:[self cachePath] error:nil][NSFileSize] longValue];
    }
    return self;
}

/// 获取未下载成功的资源
+(NSArray<BCResourceItem *> *)getUnfinishedResourceItemInCacheWithTask:(NSArray<NSURLSessionDownloadTask *> *)tasks{
    
    NSMutableArray *array = @[].mutableCopy;
    NSMutableDictionary *dict = @{}.mutableCopy;
    
    NSError *error;
    NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"BCDownloadInfo"];
    NSArray *filelist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:cachePath error:&error];
    
    if (error) { return @[]; }
    
    //找到所有记录的任务
    for(NSString *file in filelist) {
        NSString *filetype = [file pathExtension];
        if([filetype isEqualToString:@"plist"]){
            NSString *path = [cachePath stringByAppendingPathComponent:file];
            NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:path];
            BCResourceItem *model = [BCResourceItem new];
            model.url = dic[@"url"];
            model.recieveLength = [dic[@"recieveLength"] longValue];
            model.totalLength = [dic[@"totalLength"] longValue];
            model.resumeData = dic[@"resumeData"];
            [array addObject:model];
            [dict setObject:model forKey:model.url];
        }
    }
    
    //找到上次中断的任务
    for (NSURLSessionDownloadTask *task in tasks) {
        BCResourceItem *item = [dict objectForKey:task.currentRequest.URL.absoluteString];
        if (item) {
            item.downloadTask = task;
            [item suspendTask];//获取到的任务可能会自动下载 要暂停掉 并且把状态重置为未下载
            item.downloadState = BCDownloadState_unDownload;
        }
    }
    [dict removeAllObjects];
    return array;
}

//保存路径
-(NSString *)savePath{
    if (!_savePath) {
        _savePath = [BCResourceDownloadHelper getSavePathWithUrl:_url];        
    }
    return _savePath;
}

-(CGFloat)progress{
    if (_recieveLength == 0 || _totalLength == 0){
        return 0;
    }else{
        return (float)_recieveLength / (float)_totalLength;
    }
}

/// 保存下载信息
-(void)saveDownloadInfo{
    if (!_url || _url.length == 0) return;
    NSMutableDictionary *dic = @{}.mutableCopy;
    [dic setObject:_url forKey:@"url"];
    [dic setObject:@(_recieveLength) forKey:@"recieveLength"];
    [dic setObject:@(_totalLength) forKey:@"totalLength"];
    if (_resumeData) {
        [dic setObject:_resumeData forKey:@"resumeData"];
    }
    [dic setObject:[NSDate date] forKey:@"date"];
    NSString *path = [BCResourceDownloadHelper getDownloadInfoCachePathWithUrl:_url];
    BOOL result = [dic writeToFile:path atomically:YES];
    NSAssert(result, @"保存下载信息失败");
}

/// 是否存在本地文件
-(BOOL)existLocalFile{
    return [[NSFileManager defaultManager] fileExistsAtPath:[self savePath]];
}

/// 暂停下载
-(void)suspendTask{
    if (_downloadTask && _downloadState != BCDownloadState_Suspending) {
        NSLog(@"暂停: %@ -- %@",_url.lastPathComponent,_downloadTask.currentRequest.URL.absoluteString.lastPathComponent);
        _downloadState = BCDownloadState_Suspending;
        __weak typeof(self) weakself = self;
        [_downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
            if (resumeData) {
                weakself.resumeData = resumeData;
            }
        }];;
    }
}

/// 取消下载
-(void)cancelTask{
    if (_downloadTask) {
        NSLog(@"取消: %@ -- %@",_url.lastPathComponent,_downloadTask.currentRequest.URL.absoluteString.lastPathComponent);
        _downloadState = BCDownloadState_Failed;        
        _resumeData = nil;
        [_downloadTask cancel];
        ASYNC([[NSFileManager defaultManager] removeItemAtPath:[self cachePath] error:nil]);
    }
}

/// 开始下载
-(void)resumeTask{
    switch (_downloadState) {
        case BCDownloadState_unDownload:
        {
            if (_resumeData) {
                NSLog(@"继续之前的下载");
                [self resumeWithResumeData];
            }else if (_downloadTask) {
                NSLog(@"开始下载");
                 _downloadState = BCDownloadState_Downloading;
                [_downloadTask resume];
            }else{
                NSLog(@"开始创建新下载");
                [self createNewDownloadTask];
            }
        }
            break;
        case BCDownloadState_Failed: case BCDownloadState_Suspending:
        {
            if (_resumeData) {
                NSLog(@"继续下载");
                [self resumeWithResumeData];
            }else{
                NSLog(@"创建新的下载继续下载");
                [self createNewDownloadTask];
            }
        }
            break;
        default:break;
    }
}

/// 下载失败没有resumedata
-(void)failTask{
    //删除本地记录
    NSString *path = [BCResourceDownloadHelper getDownloadInfoCachePathWithUrl:_url];
    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}

/// 结束下载
-(void)finishTask{
    //移动数据
    if ([[NSFileManager defaultManager] fileExistsAtPath:[self cachePath]]) {
        NSData *data = [NSData dataWithContentsOfFile:[self cachePath]];
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"%@",str);
        [[NSFileManager defaultManager] moveItemAtPath:[self cachePath] toPath:[self savePath] error:nil];
    }else{

        NSLog(@"文件缓存不存在");
    }
    //删除本地记录
    NSString *path = [BCResourceDownloadHelper getDownloadInfoCachePathWithUrl:_url];
    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}


-(void)resumeWithResumeData{
    if(_resumeData){
        _downloadTask = [[BCResourceDownloader shareDownloader].session downloadTaskWithResumeData:_resumeData];
        _downloadState = BCDownloadState_Downloading;
        [_downloadTask resume];
    }
}

-(void)createNewDownloadTask{
    if (!_url || _url.length == 0) return;
    _downloadTask = [[BCResourceDownloader shareDownloader].session downloadTaskWithURL:[NSURL URLWithString:_url]];
    _downloadState = BCDownloadState_Downloading;
    [_downloadTask resume];
}

@end
